use std::net::SocketAddr;
use std::sync::Arc;
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Mutex;

// 客户端结构体，包含流和地址信息
#[derive(Debug)]
pub struct Client {
    stream: TcpStream,
    addr: SocketAddr,
}

impl Client {
    // 创建新客户端
    fn new(stream: TcpStream, addr: SocketAddr) -> Self {
        Self { stream, addr }
    }

    // 向客户端发送数据
    async fn send(&mut self, data: &[u8]) -> io::Result<()> {
        self.stream.write_all(data).await?;
        self.stream.flush().await?;
        Ok(())
    }

    // 获取客户端地址
    fn addr(&self) -> SocketAddr {
        self.addr
    }
}

// 定义服务器事件类型，包含客户端信息
#[derive(Debug)]
pub enum ServerEvent<'a> {
    ConnectionEstablished(&'a mut Client),
    ConnectionClosed(SocketAddr),
    DataReceived(SocketAddr, Vec<u8>),
    ErrorOccurred(SocketAddr, io::Error),
}

// 服务器结构体
pub struct TcpServer {
    listener: TcpListener,
    callback:fn(ServerEvent),
    // 可以添加其他服务器状态，如已连接客户端列表等
}

impl TcpServer {
    // 创建新服务器
    pub async fn new(addr: &str,call:fn(ServerEvent)) -> io::Result<Self> {
        let listener = TcpListener::bind(addr).await?;
        Ok(Self { listener,callback:call, })
    }

    // 启动服务器
    pub async fn start(self) {
        println!(
            "服务器启动，监听地址: {}",
            self.listener.local_addr().unwrap()
        );

        loop {
            // 等待新连接
            let (stream, addr) = match self.listener.accept().await {
                Ok((stream, addr)) => (stream, addr),
                Err(e) => {
                    eprintln!("接受连接失败: {}", e);
                    continue;
                }
            };

            // 创建客户端实例
            let mut client = Client::new(stream, addr);

            // 触发连接建立事件
            Self::handle_event(ServerEvent::ConnectionEstablished(&mut client));
            (self.callback)(ServerEvent::ConnectionEstablished(&mut client));

            // 为每个连接创建独立的任务处理
            tokio::spawn(async move {
                if let Err(e) = Self::handle_connection(client).await {
                    Self::handle_event(ServerEvent::ErrorOccurred(addr, e));
                }
                // 触发连接关闭事件
                Self::handle_event(ServerEvent::ConnectionClosed(addr));
                (self.callback)(ServerEvent::ConnectionClosed(addr));
            });
        }
    }

    // 处理单个连接
    async fn handle_connection(mut client: Client) -> io::Result<()> {
        let addr = client.addr();
        let mut buffer = [0; 1024];

        loop {
            // 读取数据
            let n = client.stream.read(&mut buffer).await?;

            if n == 0 {
                // 连接关闭
                return Ok(());
            }

            // 提取有效数据
            let data = buffer[..n].to_vec();

            // 触发数据接收事件
            Self::handle_event(ServerEvent::DataReceived(addr, data.clone()));

            // 示例：回复客户端已收到数据
            let response = format!("已收到 {} 字节的数据\n", n);
            client.send(response.as_bytes()).await?;
        }
    }
    // 处理事件的方法
    fn handle_event(event: ServerEvent) {
        match event {
            ServerEvent::ConnectionEstablished(client) => {
                println!("[事件] 客户端 {} 已连接", client.addr());
                // 这里可以添加客户端到已连接列表
            }
            ServerEvent::ConnectionClosed(addr) => {
                println!("[事件] 客户端 {} 已断开连接", addr);
                // 这里可以从已连接列表移除客户端
            }
            ServerEvent::DataReceived(addr, data) => {
                if let Ok(text) = String::from_utf8(data.clone()) {
                    println!("[事件] 从 {} 收到数据: {}", addr, text);
                } else {
                    println!("[事件] 从 {} 收到 {} 字节的二进制数据", addr, data.len());
                }
            }
            ServerEvent::ErrorOccurred(addr, e) => {
                eprintln!("[事件] 与 {} 通信时发生错误: {}", addr, e);
            }
        }
    }
}

// #[tokio::main]
// async fn main() -> io::Result<()> {
//     // 创建并启动服务器，监听本地8080端口
//     let server = TcpServer::new("127.0.0.1:8080").await?;
//     server.start().await;
//
//     Ok(())
// }
